import logging
import numpy as np

from util.util_log import setup_logging
from util.util_csv import save_csv
from util.util_image import save_img, save_img_xyz, draw_img, draw_img_xyz
from util.util_ris_pattern_2 import point_2_phi_pattern, phase_2_pattern, phase_2_pattern_xyz, eps, phase_2_bit


# 配置日志，默认打印到控制台，也可以设置打印到文件
setup_logging()
setup_logging(log_file="../files/dissertation/chapter_4/32x32-d9.3mm-FD0.905/PS-complex/log_multi_beam_PS.log")
# 获取日志记录器并记录日志
logger = logging.getLogger("[RIS-multi-beam-PS-complex]")


# 生成指向
def generate_points(theta0, phi0, phi_step, phi_max):
    points = []
    current_phi = phi0
    #
    while current_phi < phi_max:
        points.append([theta0, current_phi])
        current_phi += phi_step
    #
    return points


# ============================================= 主函数 ====================================
# 相位合成法 -- N波束 -- 核心方法
def psm_complex_beam_n(phases, bit_num):
    # complex = np.exp(1j * Phase1) + np.exp(1j * Phase2) + np.exp(1j * Phase3) + np.exp(1j * Phase4)
    rows, cols = phases[0].shape
    complex = np.zeros((rows, cols))
    for phase in phases:
        phase_rad = np.deg2rad(phase)
        complex = complex + np.exp(1j * phase_rad)
    phase_mix = np.angle(complex)
    phase_mix_deg = np.rad2deg(phase_mix)
    # 相位转换 X bit
    phaseBit_mix, phaseBitDeg_mix = phase_2_bit(phase_mix_deg, bit_num)
    return phase_mix, phaseBit_mix, phaseBitDeg_mix


# 相位合成法 -- N波束
def main_multi_beam_N(points, path_pre, bit_num):
    logger.info("main_multi_beam_N: bit_num=%d, path_pre=%s, " % (bit_num, path_pre))
    logger.info("main_multi_beam_N: num of points = %d" % (len(points)))
    logger.info("main_multi_beam_N: points = %s" % (points))
    phase_pattern_list = []
    phase_list = []
    for point in points:
        theta = point[0]
        phi = point[1]
        phase, phaseBit, pattern = point_2_phi_pattern(theta, phi, bit_num)
        phase_pattern_list.append([phase, phaseBit, pattern])
        phase_list.append(phase)
    # 相位合成法
    phase_mix, phaseBit_mix, phaseBitDeg_mix = psm_complex_beam_n(phase_list, bit_num)
    # 计算phase_mix的方向图
    phase_mix = np.deg2rad(phase_mix)
    phaseBit_mix = np.deg2rad(phaseBitDeg_mix)
    pattern_mix = phase_2_pattern(phase_mix)
    patternBit_mix = phase_2_pattern(phaseBit_mix)
    #
    # 保存结果
    logger.info("save PS-complex multi-beam N result...")
    patternBit_mix_xyz, x, y, z = phase_2_pattern_xyz(phaseBit_mix)
    # # 展示画图, 用于debug
    # for i in range(len(phase_pattern_list)):
    #     phase = phase_pattern_list[i][0]
    #     phaseBit = phase_pattern_list[i][1]
    #     pattern = phase_pattern_list[i][2]
    #     draw_img(phaseBit)
    #     draw_img(pattern)
    # draw_img(phaseBit_mix)
    # draw_img_xyz(np.abs(patternBit_mix_xyz), x, y)
    # 保存结果
    for i in range(len(phase_pattern_list)):
        phase = phase_pattern_list[i][0]
        phaseBit = phase_pattern_list[i][1]
        pattern = phase_pattern_list[i][2]
        # 保存图片
        save_img(path_pre + "phase" + str(i+1) + ".jpg", phase)
        save_img(path_pre + "phaseBit" + str(i+1) + ".jpg", phaseBit)
        save_img(path_pre + "pattern" + str(i+1) + ".jpg", pattern)
        # 保存相位结果
        save_csv(phase, path_pre + "phase" + str(i+1) + ".csv")
        save_csv(phaseBit, path_pre + "phaseBit" + str(i+1) + ".csv")
    # 保存图片
    save_img(path_pre + "phase_mix.jpg", phase_mix)             # 相位合成法(complex) -- 结果码阵
    save_img(path_pre + "pattern_mix.jpg", pattern_mix)         # 相位合成法(complex) -- 结果码阵方向图
    save_img(path_pre + "phaseBit_mix.jpg", phaseBit_mix)       # 相位合成法(complex) -- 结果码阵
    save_img(path_pre + "patternBit_mix.jpg", patternBit_mix)   # 相位合成法(complex) -- 结果码阵方向图
    save_img_xyz(path_pre + "patternBit_mix_xyz.jpg", np.abs(patternBit_mix_xyz), x, y)
    # 保存相位结果
    save_csv(phase_mix, path_pre + "phase_mix.csv")
    save_csv(phaseBit_mix, path_pre + "phaseBit_mix.csv")


# ======================================================= main 主方法 ===============================================
def main_multi_ps_complex():
    # 基于 PS-complex 的方法: 主函数
    # 1bit
    # main_multi_beam_N([[30, 0], [30, 180]], "../files/multi-beam/1bit/PS-complex/2-(30,0,30,180)/", 1)
    # main_multi_beam_N([[30, 0], [30, 90]], "../files/multi-beam/1bit/PS-complex/2-(30,0,30,90)/", 1)
    # main_multi_beam_N([[30, 0], [30, 60], [30, 120], [30, 180]],
    #                   "../files/multi-beam/1bit/PS-complex/4-(30,0,30,60,30,120,30,180)/", 1)
    main_multi_beam_N([[30, 0], [30, 90], [30, 180], [30, 270]],
                      "../files/dissertation/chapter_4/32x32-d9.3mm-FD0.905/PS-complex/B4-(30,0)-(30,90)-(30,180)-(30,270)/", 1)
    main_multi_beam_N(generate_points(30, 0, 45, 360),
                      "../files/dissertation/chapter_4/32x32-d9.3mm-FD0.905/PS-complex/B8-(30,45step)/", 1)
    # main_multi_beam_N(generate_points(30, 0, 22.5, 360), "../files/multi-beam/1bit/PS-complex/16-(30,22.5step)/", 1)
    # main_multi_beam_N(generate_points(30, 0, 11.25, 360), "../files/multi-beam/1bit/PS-complex/32-(30,11.25step)/", 1)
    # 2bit
    # main_multi_beam_N([[30, 0], [30, 180]], "../files/multi-beam/2bit/PS-complex/2-(30,0,30,180)/", 2)
    # main_multi_beam_N([[30, 0], [30, 90]], "../files/multi-beam/2bit/PS-complex/2-(30,0,30,90)/", 2)
    # main_multi_beam_N([[30, 0], [30, 60], [30, 120], [30, 180]],
    #                   "../files/multi-beam/2bit/PS-complex/4-(30,0,30,60,30,120,30,180)/", 2)
    # main_multi_beam_N([[30, 0], [30, 90], [30, 180], [30, 270]],
    #                   "../files/multi-beam/2bit/PS-complex/4-(30,0,30,90,30,180,30,270)/", 2)
    # main_multi_beam_N(generate_points(30, 0, 45, 360), "../files/multi-beam/2bit/PS-complex/8-(30,45step)/", 2)
    # main_multi_beam_N(generate_points(30, 0, 22.5, 360), "../files/multi-beam/2bit/PS-complex/16-(30,22.5step)/", 2)
    # main_multi_beam_N(generate_points(30, 0, 11.25, 360), "../files/multi-beam/2bit/PS-complex/32-(30,11.25step)/", 2)


# 主函数 - 非均匀分区
def main_multi_ps_complex_nonuniform():
    # part 0: 参数
    # 四波束 (83,230),(65,93),(13,138),(25,156) 参数
    main_multi_beam_N([[83,230],[65,93],[13,138],[25,156]],
                      "../files/multi-beam-scan/1bit/rand-4/PS-complex/", 1)
    # 七波束 (30,110),(12,286),(48,273),(48,133),(57,135),(45,167),(85,204) 参数
    main_multi_beam_N([[30,110],[12,286],[48,273],[48,133],[57,135],[45,167],[85,204]],
                      "../files/multi-beam-scan/1bit/rand-7/PS-complex/", 1)
    # 八波束 (22,50),(56,349),(5,142),(85,54),(61,327),(61,195),(80,153),(2,336) 参数
    main_multi_beam_N([[22,50],[56,349],[5,142],[85,54],[61,327],[61,195],[80,153],[2,336]],
                      "../files/multi-beam-scan/1bit/rand-8/PS-complex/", 1)
    # 16波束 (13,70),(51,319),(35,103),(50,218),(63,148),(71,267),(75,196),(67,275),
    #       (20,32),(59,80),(20,355),(2,336),(0,81),(83,48),(3,269),(14,276) 参数
    main_multi_beam_N([[13,70],[51,319],[35,103],[50,218],[63,148],[71,267],[75,196],[67,275],
                       [20,32],[59,80],[20,355],[2,336],[0,81],[83,48],[3,269],[14,276]],
                      "../files/multi-beam-scan/1bit/rand-16/PS-complex/", 1)




if __name__ == '__main__':
    logger.info("RIS-multi-beam-PS-complex:")
    main_multi_ps_complex()
    # main_multi_ps_complex_nonuniform()